package gsw.tool.pluggable.core;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.os.IBinder;
import android.os.RemoteException;

import gsw.tool.pluggable.hook.hook.HookTool;
import gsw.tool.pluggable.pm.MPackageManagerService;
import gsw.tool.pluggable.pm.parser.PackageMapPlugin;
import gsw.tool.pluggable.IPluiginManager;

/**
 * 插件化框架
 * 注意：该框架只适用于API25以下
 */
public class PluginManager implements ServiceConnection {
    private static PluginManager pluginManager;
    //自定义的PMS
    private IPluiginManager PMS;
    //宿主的上下文
    private Context context;

    private PluginManager() {
    }

    public static PluginManager getInstance() {
        if (pluginManager == null) {
            synchronized (PackageMapPlugin.class) {
                if (pluginManager == null) {
                    pluginManager = new PluginManager();
                }
            }
        }
        return pluginManager;
    }


    /**
     * 初始化操作
     * 需要在Application.onCreate()中调用，因为加载一个插件，就会开启一个新的进程。
     *
     * @param context 宿主的上下文
     */
    public void init(Context context) {
        this.context = context;
        //添加Hook点：给宿主Application调用
        HookTool.installHook();
        //开启运行自定义PMS的远程服务
        connectToService();
    }

    /**
     * 获取宿主的上下文
     *
     * @return 宿主的上下文
     */
    public static Context getContext() {
        return getInstance().context;
    }

    /**
     * 开启运行自定义PMS的远程服务
     */
    public void connectToService() {
        if (PMS == null) {
            try {
                Intent intent = new Intent(context, MPackageManagerService.class);
                context.startService(intent);
                context.bindService(intent, this, Context.BIND_AUTO_CREATE);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 开启PMS的服务后，获取自定义的PMS对象
     *
     * @param name    服务的ComponentName
     * @param service 自定义的PMS对象
     */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        PMS = IPluiginManager.Stub.asInterface(service);
    }

    /**
     * PMS的服务断开后
     *
     * @param name
     */
    @Override
    public void onServiceDisconnected(ComponentName name) {
    }

    /**
     * 使用自定义的PMS，安装插件APK
     *
     * @param filepath 插件APK的路径
     * @return 安装结果：0代表成功，-1代表失败
     */
    public int installPackage(String filepath) {
        return installPackage(filepath, 0);
    }

    /**
     * 使用自定义的PMS，安装插件APK
     *
     * @param filepath 插件APK的路径
     * @param flags    标志位
     * @return 安装结果：0代表成功，-1代表失败
     */
    public int installPackage(String filepath, int flags) {
        try {
            if (PMS != null) {
                int result = PMS.installPackage(filepath, flags);
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 卸载插件APK,根据插件包名卸载
     *
     * @param packageName 插件包名
     * @param flags       标志位
     * @return 卸载结果：0代表成功，-1代表失败
     */
    public int deletePackage(String packageName, int flags) {
        try {
            if (PMS != null) {
                int result = PMS.deletePackage(packageName, flags);
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }


    /**
     * 根据插件的组件名获取插件组件的ActivityInfo
     *
     * @param componentName 插件的组件名
     * @param flags         标志位
     * @return 插件组件的ActivityInfo
     */
    public ActivityInfo getActivityInfo(ComponentName componentName, int flags) {
        if (componentName == null) {
            return null;
        }
        if (PMS != null) {
            try {
                return PMS.getActivityInfo(componentName, flags);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据意图选择代理组件
     *
     * @param intent 跳转的意图
     * @return 代理组件
     */
    public ActivityInfo selectProxyActivity(Intent intent) {
        if (PMS != null) {
            try {
                return PMS.selectStubActivityInfoByIntent(intent);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据插件的组件名获取插件的ApplicationInfo
     *
     * @param componentName 插件的组件名
     * @param flag          标志位
     * @return 插件的ApplicationInfo
     */
    public ApplicationInfo getApplicationInfo(ComponentName componentName, int flag) {
        if (PMS != null) {
            try {
                return PMS.getApplicationInfo(componentName.getPackageName(), flag);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     * 开启代理组件的进程时，初始自定义AMS中的代理进程的信息
     *
     * @param stubProcessName   代理进程名
     * @param targetProcessName 目标进程名
     * @param targetPkg         目标包名
     */
    public void onOpenPluginProcess(String stubProcessName, String targetProcessName, String targetPkg) {
        try {
            if (PMS != null) {
                PMS.onOpenPluginProcess(stubProcessName, targetProcessName, targetPkg);
            } else {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 按需加载插件APK的loadedApk对象到宿主中
     *
     * @param component 组件的ComponentName
     */
    public static void preLoadApk(ComponentName component) {
        PluginTool.preLoadApk(component);
    }
}
